// #define print(...)
#define map_t map
#define get_num(p,tail,num)                 \
            if(p==tail || !isdigit(*p))     \
                num = 1;                    \
            while(p!=tail && isdigit(*p))   \
                num = (*p++)-'0' + num*10;

#define get_atom(p,tail,atom)               \
            atom.insert(atom.end(), *p);    \
            while(++p<tail && islower(*p))  \
                atom.insert(atom.end(), *p);

class Solution {
public:
    string countOfAtoms(string formula){
        list< map_t<string,int> > stk(1);
        int n = 0;
        auto it=formula.begin();
        while(it!=formula.end()){
            switch(*it){
            case '(':
                stk.push_front(map_t<string,int>());
                ++it;
                break;
            case ')':
                n = 0;
                ++it;
                get_num(it, formula.end(), n)
                {
                    auto tmp = stk.front();
                    stk.pop_front();
                    for(auto&[atom,count]:tmp)
                        stk.front()[atom] += count*n;
                }
                break;
            default:
                string atom; n = 0;
                get_atom(it, formula.end(), atom)
                print(atom, "-")
                get_num(it, formula.end(), n)
                print(n, "\n")
                stk.front()[atom] += n;
                break;
            }
            print(stk, "\n")
        }
        
        string s;
        s.reserve(formula.size());
        for(auto &[a,n]:stk.front()){
            s.insert(s.size(), a);
            if(n>1)
                s.insert(s.size(), to_string(n));
        }
        return s;
    }
};
